#include "graphic_particle_system.h"

// .. REFERENCES

#include "primitives.h"

// -- PUBLIC

// .. CONSTRUCTORS

GRAPHIC_PARTICLE_SYSTEM::GRAPHIC_PARTICLE_SYSTEM() :
    OBJECT(),
    ParticleTable(),
    Emitter(),
    ModifierTable(),
    Displayer(),
    Flags( 0 ),
    ItIsPaused( false ),
    EmissionIsPaused( false )
{
}

// .. OPERATIONS

VOID GRAPHIC_PARTICLE_SYSTEM::Initialize(
    const COUNT particle_count,
    const TEXT & particle_texture
    )
{
    INDEX
        modifier_index;

    ParticleTable.Initialize( particle_count );
    Displayer->Initialize( particle_texture, ParticleTable );

    for_each_table_index( modifier_index, ModifierTable )
    {
        Flags |= ModifierTable[ modifier_index ]->GetFlags();
    }

    Displayer->SetFlags( Flags );
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::Update(
    const TIMER & time_step
    )
{
    INDEX
        modifier_index,
        table_index;

    if ( ! ItIsPaused )
    {
        if( Emitter->GetCurrentTime() < Emitter->GetDuration() )
        {
            Emitter->Emit( ParticleTable, time_step );

            for_each_table_index( modifier_index, ModifierTable )
            {
            	for_each_table_index( table_index, ParticleTable.GetParticleTable() )
                {
                    ModifierTable[ modifier_index ]->Modify( ParticleTable.GetParticleTable()[ table_index ], time_step );
                }
            }
        }
        else
        {
            if( Emitter->IsLoop() )
            {
                Emitter->SetCurrentTime( 0 );
            }
        }
    }
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::Reset()
{ 
    Emitter->Reset();
    ParticleTable.Reset();
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::Render()
{
    Displayer->Render( ParticleTable );
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::AddModifier(
    const GRAPHIC_PARTICLE_MODIFIER::REF & modifier 
    )
{
    ModifierTable.Add( modifier );
}

// ~~ 

VOID GRAPHIC_PARTICLE_SYSTEM::SetPosition(
    const MATH_VECTOR_3 & position
    )
{
    Displayer->UpdateConstants( position );
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::Pause(
    const BOOL it_must_pause
    )
{
    ItIsPaused = it_must_pause;
}

// ~~

VOID GRAPHIC_PARTICLE_SYSTEM::PauseEmitter(
    const BOOL emitter_must_be_paused
    )
{
    EmissionIsPaused = emitter_must_be_paused;
    Emitter->Pause( emitter_must_be_paused );
}
